package com.hemerasolutions.v2trainer.component.detail;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.hemerasolutions.v2trainer.component.BaseComponent;
import com.hemerasolutions.v2trainer.component.interfaces.detail.StepCompInterface;
import com.hemerasolutions.v2trainer.component.interfaces.list.IntensityZoneListCompInterface;
import com.hemerasolutions.v2trainer.component.interfaces.list.ModalityIZListCompInterface;
import com.hemerasolutions.v2trainer.component.interfaces.list.StepListCompInterface;
import com.hemerasolutions.v2trainer.model.exercise.executions.Execution;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityExecution;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityModTable;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityModZone;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityTable;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityZone;
import com.hemerasolutions.v2trainer.model.library.Library;
import com.hemerasolutions.v2trainer.model.modality.Modality;
import com.hemerasolutions.v2trainer.model.step.Step;
import com.hemerasolutions.v2trainer.model.step.substep.ExerciseGroupStep;
import com.hemerasolutions.v2trainer.model.step.substep.ExerciseGroupedStep;
import com.hemerasolutions.v2trainer.model.training.TrainingType;
import com.hemerasolutions.v2trainer.model.unit.volume.VolumeFactor;
import com.hemerasolutions.v2trainer.model.unit.volume.VolumeType;

@Component("stepComp")
@Scope("prototype")
public class StepComp extends BaseComponent implements StepCompInterface {

	private static final long serialVersionUID = 1L;
	
	private static final String WORKOUTPANEL_STYLECLASS = "ui-training";

	private List<String> variations = Arrays.asList("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");

	private StepListCompInterface parentPanelHandler;

	private Step step;
	
	private List<TrainingType> templateTrainingTypes;
	
	private List<Modality> templateModalitys;
	
	private List<Execution> templateExecutions;
	
	private List<VolumeType> templateVolumeTypes;
	
	private List<IntensityModZone> templateIntensityModZones;
	
	private List<VolumeFactor> templateVolumeFactors;

	private List<IntensityZone> exerciseIntensityZones;
	
	private List<VolumeType> exerciseVolumeTypes;
	
	private List<VolumeFactor> exerciseVolumeFactors;

	private List<Execution> egExecutions;
	
	private List<VolumeType> egVolumeTypes;
	
	private List<IntensityModZone> egIntensityModZones;
	
	private List<VolumeFactor> egVolumeFactors;
	
	public StepComp(){
		super();
	}
	

	@Override
	public void changeStep(){
		this.parentPanelHandler.stepChanged(this.step);
	}
	
	@Override
	public void deleteStep(ActionEvent ev){
		parentPanelHandler.deleteChild(ev);
		this.changeStep();
	}
    	
	@Override
	public void updateParentWorkout(ActionEvent ev) {
		this.updatePFComponnent(this.getParentWorkoutPanel(ev.getComponent()));
	}


	@Override
	public void updateParentWorkout(javax.faces.event.AjaxBehaviorEvent ev) {
		this.updatePFComponnent(this.getParentWorkoutPanel(ev.getComponent()));
	}
	

	private String getParentWorkoutPanel(UIComponent component) {
		String styleClass = (String)component.getAttributes().get("styleClass");
		if (styleClass != null && styleClass.contains(WORKOUTPANEL_STYLECLASS)){
			return component.getClientId();
		}else if(component.getParent() != null){
			return this.getParentWorkoutPanel(component.getParent());
		}else{
			return "@none";
		}
	}


	@Override
	public void refresh(){
    	this.loadStep();
    }

	@Override
	public void toggleStep(ActionEvent ev ){
		this.getStep().setMark(!this.getStep().isMark());
	}
    
    
    @Override
	public void loadStep(){
		
    	if(this.getStep().getType() == Step.EXERCISE_TEMPLATE ){
    		this.fillTemplateTrainingTypes();
    		if(this.getStep().getTemplateExercise().getTrainingType() == null){
    			this.getStep().getTemplateExercise().setTrainingType(this.templateTrainingTypes.get(0));
    		}
    		
    		this.fillTemplateModalitys();
    		if( this.getStep().getTemplateExercise().getModality() == null &&
    			this.templateModalitys != null &&
    			!this.templateModalitys.isEmpty()){
    			this.getStep().getTemplateExercise().setModality(this.templateModalitys.get(0));
    		}
    		
    		this.fillTemplateExecutions();
    		if( this.getStep().getTemplateExercise().getExecution() == null &&
    			this.templateExecutions != null &&
    			!this.templateExecutions.isEmpty()){
    			this.getStep().getTemplateExercise().setExecution(this.templateExecutions.get(0));
       		}

    		this.fillTemplateIntensityModZones();
    		if( this.getStep().getTemplateExercise().getIntensityModZone() == null &&
    			this.templateIntensityModZones != null &&
    			!this.templateIntensityModZones.isEmpty()){
    			this.getStep().getTemplateExercise().setIntensityModZone(this.templateIntensityModZones.get(0));
       		}

    		
    		this.fillTemplateVolumeTypes();
    		if( this.getStep().getTemplateExercise().getVolumeType() == null &&
        			this.templateVolumeTypes != null &&
        			!this.templateVolumeTypes.isEmpty()){
        			this.getStep().getTemplateExercise().setVolumeType(this.templateVolumeTypes.get(0));
           		}

    		this.fillTemplateVolumeFactors();
    		if( this.getStep().getTemplateExercise().getVolumeFactor() == null &&
        			this.templateVolumeFactors != null &&
        			!this.templateVolumeFactors.isEmpty()){
        			this.getStep().getTemplateExercise().setVolumeFactor(this.templateVolumeFactors.get(0));
        	}
    		

    	}else if(this.getStep().getType() == Step.EXERCISE_STEP ){
    		if( this.getStep().getExerciseStep().getExecution() == null &&
    			this.getStep().getExerciseStep().getExercise().getExecutions() != null &&
   				!this.getStep().getExerciseStep().getExercise().getExecutions().isEmpty()){
    			this.getStep().getExerciseStep().setExecution(this.getStep().getExerciseStep().getExercise().getExecutions().get(0));
    		}

    		this.fillExerciseIntensityZones();
    		if(	this.getStep().getExerciseStep().getIntensityZone() == null &&
    			this.exerciseIntensityZones != null	&&
    			!this.exerciseIntensityZones.isEmpty()){
    			this.getStep().getExerciseStep().setIntensityZone(this.exerciseIntensityZones.get(0));
    		}
    		
    		this.fillExerciseVolumeTypes();
    		if(	this.getStep().getExerciseStep().getVolumeType() == null &&
        			this.exerciseVolumeTypes != null	&&
        			!this.exerciseVolumeTypes.isEmpty()){
        			this.getStep().getExerciseStep().setVolumeType(this.exerciseVolumeTypes.get(0));
    		}		
    		
    		this.fillExerciseVolumeFactors();
       		if(	this.getStep().getExerciseStep().getVolumeFactor() == null &&
        			this.exerciseVolumeFactors != null	&&
        			!this.exerciseVolumeFactors.isEmpty()){
        			this.getStep().getExerciseStep().setVolumeFactor(this.exerciseVolumeFactors.get(0));
    		}		

       		
    	}else if(this.getStep().getType() == Step.EXERCISE_GROUPED){

    	}else if(this.getStep().getType() == Step.EXERCISE_GROUP){

    		this.fillEgExecutions();
    		if( this.getStep().getExerciseGroupStep().getExecution() == null &&
    			this.egExecutions != null &&
    			!this.egExecutions.isEmpty()){
    			this.getStep().getExerciseGroupStep().setExecution(this.egExecutions.get(0));
       		}

    		this.fillEgIntensityModZones();
    		if( this.getStep().getExerciseGroupStep().getIntensityModZone() == null &&
    			this.egIntensityModZones != null &&
    			!this.egIntensityModZones.isEmpty()){
    			this.getStep().getExerciseGroupStep().setIntensityModZone(this.egIntensityModZones.get(0));
       		}

    		
    		this.fillEgVolumeTypes();
    		if( this.getStep().getExerciseGroupStep().getVolumeType() == null &&
        			this.egVolumeTypes != null &&
        			!this.egVolumeTypes.isEmpty()){
        			this.getStep().getExerciseGroupStep().setVolumeType(this.egVolumeTypes.get(0));
           		}

    		this.fillEgVolumeFactors();
    		if( this.getStep().getExerciseGroupStep().getVolumeFactor() == null &&
        			this.egVolumeFactors != null &&
        			!this.egVolumeFactors.isEmpty()){
        			this.getStep().getExerciseGroupStep().setVolumeFactor(this.egVolumeFactors.get(0));
        	}    		
    	
    		ExerciseGroupStep egs = this.getStep().getExerciseGroupStep();
    		
    		for(Step stepAux:this.getStep().getSteps()){
    			ExerciseGroupedStep egds = stepAux.getExerciseGroupedStep();
    			try{
        			egds.setIntensityZone(egs.getIntensityZone(egds.getExercise()));    		
    			}catch(Exception ex){
    				this.showErrorMessage(this.localizedText("Error"), this.localizedText("ModalityAndExerciseWithImcompatibleIZ") + ":" + egds.getExercise().getName());
    			}
    		}
    	}
    }    
    

	@Override
    public void toViewIz(){
		IntensityZoneListCompInterface izHandler = this.parentPanelHandler.getIzHandler();
		
		if(this.getStep().getType() == Step.EXERCISE_STEP){
       		izHandler.setExercise(this.getStep().getExerciseStep().getExercise());
       		izHandler.setModality(this.getStep().getExerciseStep().getExercise().getModality());
       		izHandler.refresh();			
		}else if(this.getStep().getType() == Step.EXERCISE_GROUPED){
       		izHandler.setExercise(this.getStep().getExerciseGroupedStep().getExercise());
       		izHandler.setModality(this.getStep().getExerciseGroupedStep().getExercise().getModality());
       		izHandler.refresh();    	
		}
			
    }
    
	@Override
    public void toViewImz(){
		ModalityIZListCompInterface imzHandler =  this.parentPanelHandler.getImzHandler();

		
		if(this.getStep().getType() == Step.EXERCISE_TEMPLATE){
			if(this.getStep().getTemplateExercise().getModality() != null){
	    		imzHandler.setModality(this.getStep().getTemplateExercise().getModality());
	    		imzHandler.refresh();
			}
		}else{
			imzHandler.setModality(this.getStep().getExerciseGroupStep().getModality());
			imzHandler.refresh();	
		}
		
    }

	
	@Override
	public void changeEgImz(){
    	this.loadStep();    	
    	this.changeStep();
	}

	
	@Override
    public void changeEgExecution(){
		this.getStep().getExerciseGroupStep().setIntensityModZone(null);		
    	this.loadStep();    	
    	this.changeStep();
	}


	@Override
    public void changeEgVolumeType(){
		this.getStep().getExerciseGroupStep().setVolumeFactor(null);
		this.getStep().getExerciseGroupStep().setValue(0);
    	this.loadStep();    	
    	this.changeStep();
    }
    
	@Override
	public void changeExerciseExecution(){

		this.getStep().getExerciseStep().setIntensityZone(null);
		this.getStep().getExerciseStep().setVolumeFactor(null);
		this.getStep().getExerciseStep().setVolumeType(null);
		this.getStep().getExerciseStep().setValue(0);
    	this.loadStep();
    	this.changeStep();

	}

	@Override
	public void changeExerciseIntensityLevel(){
		this.getStep().getExerciseStep().setIntensityZone(null);
    	this.loadStep();
    	this.changeStep();

	}
	
	@Override
	public void changeExerciseVolumeType(){
		this.getStep().getExerciseStep().setVolumeFactor(null);
		this.getStep().getExerciseStep().setValue(0);	
    	this.loadStep();
    	this.changeStep();
	}
	
	@Override
	public void changeTemplateTrainingType(){
		this.getStep().getTemplateExercise().setModality(null);
		this.getStep().getTemplateExercise().setExecution(null);
		this.getStep().getTemplateExercise().setIntensityModZone(null);		
		this.getStep().getTemplateExercise().setVolumeType(null);
		this.getStep().getTemplateExercise().setValue(0);
    	this.loadStep();
    	this.changeStep();
	}
	
	@Override
	public void changeTemplateModality(){
		this.getStep().getTemplateExercise().setExecution(null);
		this.getStep().getTemplateExercise().setIntensityModZone(null);		
		this.getStep().getTemplateExercise().setVolumeType(null);
		this.getStep().getTemplateExercise().setValue(0);
    	this.loadStep();
    	this.changeStep();
	}

	@Override
	public void changeTemplateExecution(){
		this.getStep().getTemplateExercise().setIntensityModZone(null);		
    	this.loadStep();
    	this.changeStep();
	}

	@Override
	public void changeVolumeType(){
		this.getStep().getTemplateExercise().setVolumeFactor(null);
		this.getStep().getTemplateExercise().setValue(0);
    	this.loadStep();
    	this.changeStep();
	}

	@Override
	public void changeVolumeFactor(){
    	this.loadStep();
    	this.changeStep();
	}
	

	@Override
	public void fillTemplateTrainingTypes(){
		this.templateTrainingTypes = this.getParentPanelHandler().getTtDao().list();
	}


	@Override
	public void fillTemplateModalitys(){
		
		this.templateModalitys = new ArrayList<Modality>();

		for(Library lib:this.getActiveUserAllowedLibrarys()){
			for(Modality mod:lib.getVersionableModalitys()){
				if(mod.getTrainingType().equals(this.getStep().getTemplateExercise().getTrainingType())){
					this.templateModalitys.add(mod);
				}
			}
		}
	}
	

	@Override
	public void fillTemplateExecutions(){
		this.templateExecutions =  new ArrayList<Execution>();

		if(this.getStep().getTemplateExercise().getModality() != null){
			this.templateExecutions.addAll(this.getStep().getTemplateExercise().getModality().getExecutions());
		}
	}

	@Override
	public void fillExerciseIntensityZones(){
		this.exerciseIntensityZones = new ArrayList<IntensityZone>();
		
		if(this.getStep().getExerciseStep().getExecution() != null ){	
			for(IntensityExecution ie:this.getStep().getExerciseStep().getExercise().getIntensityExecutions()){
				if(ie.getExecution().equals(this.getStep().getExerciseStep().getExecution())){
					for(IntensityTable it: ie.getIntensityTables()){
						if(it.getLevel() == this.getStep().getTrainingStep().getLevel()){
							this.exerciseIntensityZones.addAll(it.getIntensitys());
							break;
						}
					}
				}
			}	
		}
	}
	
	@Override
	public void fillTemplateIntensityModZones(){
		this.templateIntensityModZones = new ArrayList<IntensityModZone>();
		
		if(this.getStep().getTemplateExercise().getExecution() != null ){	
			for(IntensityModTable im:this.getStep().getTemplateExercise().getModality().getIntensityModTables()){
				if(im.getExecution().getName().equals(this.getStep().getTemplateExercise().getExecution().getName())){
					templateIntensityModZones.addAll(im.getIntensityModZones());
					break;
				}
			}
		}		
	}
	
	@Override
	public void fillExerciseVolumeTypes(){
		this.exerciseVolumeTypes = new ArrayList<VolumeType>();
		
		if(this.getStep().getExerciseStep().getExercise().getModality() != null){
			this.exerciseVolumeTypes.addAll(this.getStep().getExerciseStep().getExercise().getModality().getVolumeTypes());
		}
	}
	
	@Override
	public void fillTemplateVolumeTypes(){
		this.templateVolumeTypes = new ArrayList<VolumeType>();
		
		if(this.getStep().getTemplateExercise().getModality() != null){
			templateVolumeTypes.addAll(this.getStep().getTemplateExercise().getModality().getVolumeTypes());
		}
	}
	
	@Override
	public void fillExerciseVolumeFactors(){
		this.exerciseVolumeFactors = new ArrayList<VolumeFactor>();
		
		if(this.getStep().getExerciseStep().getVolumeType() != null){
			exerciseVolumeFactors.addAll(this.getStep().getExerciseStep().getVolumeType().getVolumeFactors());
		}
	}

	@Override
	public void fillTemplateVolumeFactors(){
		this.templateVolumeFactors = new ArrayList<VolumeFactor>();
		
		if(this.getStep().getTemplateExercise().getVolumeType() != null){
			templateVolumeFactors.addAll(this.getStep().getTemplateExercise().getVolumeType().getVolumeFactors());
		}
	}


	@Override
	public void fillEgExecutions(){
		this.egExecutions =  new ArrayList<Execution>();

		if(this.getStep().getExerciseGroupStep().getModality() != null){
			this.egExecutions.addAll(this.getStep().getExerciseGroupStep().getModality().getExecutions());
		}
	}


	@Override
	public void fillEgIntensityModZones(){
		this.egIntensityModZones = new ArrayList<IntensityModZone>();
		
		if(this.getStep().getExerciseGroupStep().getExecution() != null ){	
			for(IntensityModTable im:this.getStep().getExerciseGroupStep().getModality().getIntensityModTables()){
				if(im.getExecution().getName().equals(this.getStep().getExerciseGroupStep().getExecution().getName())){
					egIntensityModZones.addAll(im.getIntensityModZones());
					break;
				}
			}
		}		
	}
	
	
	@Override
	public void fillEgVolumeTypes(){
		this.egVolumeTypes = new ArrayList<VolumeType>();
		
		if(this.getStep().getExerciseGroupStep().getModality() != null){
			egVolumeTypes.addAll(this.getStep().getExerciseGroupStep().getModality().getVolumeTypes());
		}
	}
	

	@Override
	public void fillEgVolumeFactors(){
		this.egVolumeFactors = new ArrayList<VolumeFactor>();
		
		if(this.getStep().getExerciseGroupStep().getVolumeType() != null){
			egVolumeFactors.addAll(this.getStep().getExerciseGroupStep().getVolumeType().getVolumeFactors());
		}
	}

	
	@Override
	public void calendarChangeListener(ValueChangeEvent e){
		System.out.println("veio");
	}
	
	@Override
	public List<String> getVariations() {
		return variations;
	}

	@Override
	public void setVariations(List<String> variations) {
		this.variations = variations;
	}

	@Override
	public Step getStep() {
		return this.step;
	}

	@Override
	public void setStep(Step step) {
		this.step = step;
	}


	@Override
	public StepListCompInterface getParentPanelHandler() {
		return parentPanelHandler;
	}


	@Override
	public void setParentPanelHandler(StepListCompInterface parentPanelHandler) {
		this.parentPanelHandler = parentPanelHandler;
	}


	@Override
	public List<TrainingType> getTemplateTrainingTypes() {
		return templateTrainingTypes;
	}


	@Override
	public void setTemplateTrainingTypes(List<TrainingType> templateTrainingTypes) {
		this.templateTrainingTypes = templateTrainingTypes;
	}


	@Override
	public List<Modality> getTemplateModalitys() {
		return templateModalitys;
	}


	@Override
	public void setTemplateModalitys(List<Modality> templateModalitys) {
		this.templateModalitys = templateModalitys;
	}


	@Override
	public List<Execution> getTemplateExecutions() {
		return templateExecutions;
	}


	@Override
	public void setTemplateExecutions(List<Execution> templateExecutions) {
		this.templateExecutions = templateExecutions;
	}


	@Override
	public List<VolumeType> getTemplateVolumeTypes() {
		return templateVolumeTypes;
	}


	@Override
	public void setTemplateVolumeTypes(List<VolumeType> templateVolumeTypes) {
		this.templateVolumeTypes = templateVolumeTypes;
	}


	@Override
	public List<IntensityModZone> getTemplateIntensityModZones() {
		return templateIntensityModZones;
	}


	@Override
	public void setTemplateIntensityModZones(
			List<IntensityModZone> templateIntensityModZones) {
		this.templateIntensityModZones = templateIntensityModZones;
	}


	@Override
	public List<VolumeFactor> getTemplateVolumeFactors() {
		return templateVolumeFactors;
	}


	@Override
	public void setTemplateVolumeFactors(List<VolumeFactor> templateVolumeFactors) {
		this.templateVolumeFactors = templateVolumeFactors;
	}


	@Override
	public List<IntensityZone> getExerciseIntensityZones() {
		return exerciseIntensityZones;
	}


	@Override
	public void setExerciseIntensityZones(List<IntensityZone> exerciseIntensityZones) {
		this.exerciseIntensityZones = exerciseIntensityZones;
	}


	@Override
	public List<VolumeType> getExerciseVolumeTypes() {
		return exerciseVolumeTypes;
	}


	@Override
	public void setExerciseVolumeTypes(List<VolumeType> exerciseVolumeTypes) {
		this.exerciseVolumeTypes = exerciseVolumeTypes;
	}


	@Override
	public List<VolumeFactor> getExerciseVolumeFactors() {
		return exerciseVolumeFactors;
	}


	@Override
	public void setExerciseVolumeFactors(List<VolumeFactor> exerciseVolumeFactors) {
		this.exerciseVolumeFactors = exerciseVolumeFactors;
	}



	@Override
	public List<Execution> getEgExecutions() {
		return egExecutions;
	}


	@Override
	public void setEgExecutions(List<Execution> egExecutions) {
		this.egExecutions = egExecutions;
	}


	@Override
	public List<VolumeType> getEgVolumeTypes() {
		return egVolumeTypes;
	}


	@Override
	public void setEgVolumeTypes(List<VolumeType> egVolumeTypes) {
		this.egVolumeTypes = egVolumeTypes;
	}


	@Override
	public List<IntensityModZone> getEgIntensityModZones() {
		return egIntensityModZones;
	}


	@Override
	public void setEgIntensityModZones(List<IntensityModZone> egIntensityModZones) {
		this.egIntensityModZones = egIntensityModZones;
	}


	@Override
	public List<VolumeFactor> getEgVolumeFactors() {
		return egVolumeFactors;
	}


	@Override
	public void setEgVolumeFactors(List<VolumeFactor> egVolumeFactors) {
		this.egVolumeFactors = egVolumeFactors;
	}




	
}
